package com.hugang.juc.error;

import sun.misc.VM;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

/**
 * @author hg
 * @date 2020/8/26 16:41
 */
public class OutOfMemoryErrorDemo {


    public static void main(String[] args) {
        //int i = 1;
        //while (true){
        //    Enhancer enhancer = new Enhancer();
        //    enhancer.setSuperclass(T.class);
        //    enhancer.setUseCache(false);
        //    enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> methodProxy.invokeSuper(o,args));
        //    System.out.println(i++);
        //}
        test1();
    }


    /**
     * unable to create new native thread
     *
     */
    private static void test4() {
        int i = 1;
        while (true){
            System.out.println(i++);
            new Thread(()->{
                try {
                    TimeUnit.SECONDS.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }

    /**
     * Direct buffer memory
     * 堆外内存溢出，默认值为物理内存的1/4，设置-Xmx也可改变此值
     * -XX:MaxDirectMemorySize=5m
     */
    private static void test3() {
        System.out.println("堆外内存大小： " + VM.maxDirectMemory() / (double)1024/1024 + "MB");
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        ByteBuffer.allocateDirect(6 * 1024 * 1024);
    }

    /**
     * GC overhead limit exceeded
     * -Xmx10m -XX:MaxDirectMemorySize=5m
     */
    private static void test2() {
        int i = 0;
        ArrayList<String> strings = new ArrayList<>();
        while (true){
            strings.add(String.valueOf(i++).intern());
        }
    }

    /**
     * -Xmx5m
     * Java heap space
     */
    private static void test1() {
        HashMap<Object, Object> map = new HashMap<>();
        while (true){
            byte[] bytes = new byte[10 * 1024 * 1024];
            map.put(bytes,bytes);
            System.out.println(bytes);
            try {
                TimeUnit.MILLISECONDS.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
    static class T{}
}
